package com.spsoft.vatoutinv.service.vmsenterpriseinfo.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.spsoft.core.enums.ResponseEnum;
import com.spsoft.core.exception.BusinessException;
import com.spsoft.core.model.Result;
import com.spsoft.core.model.bo.TokenUser;
import com.spsoft.core.model.leqidmz.param.BaseNsrRequestParams;
import com.spsoft.core.model.leqidmz.response.QueryEnterpriseInfoVO;
import com.spsoft.core.utils.BeanUtils;
import com.spsoft.core.utils.SecurityUtils;
import com.spsoft.einvoicetodmz.service.DmzApiClientService;
import com.spsoft.vatoutinv.constants.CommonConstant;
import com.spsoft.vatoutinv.entity.vmsenterpriseinfo.VmsEnterpriseInfo;
import com.spsoft.vatoutinv.entity.vmsenterpriseinfo.VmsEnterpriseInfoLog;
import com.spsoft.vatoutinv.enums.EnterpriseInfoStateEnum;
import com.spsoft.vatoutinv.mapper.VmsEnterpriseInfoLogMapper;
import com.spsoft.vatoutinv.mapper.VmsEnterpriseInfoMapper;
import com.spsoft.vatoutinv.model.vo.vmsenterpriseinfo.VmsEnterpriseInfoVO;
import com.spsoft.vatoutinv.service.vmsenterpriseinfo.VmsEnterpriseInfoService;
import com.spsoft.vms.redis.RedisService;
import com.spsoft.vms.redis.constant.RedisConstant;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 纳税人基本信息查询-企业基本信息、税务信息、财务信息;--主键序列 SEQ_VMS_ENTERPRISE_INFO 服务实现类
 * </p>
 *
 * @author wangy
 * @since 2023-11-22
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class VmsEnterpriseInfoServiceImpl extends ServiceImpl<VmsEnterpriseInfoMapper, VmsEnterpriseInfo> implements VmsEnterpriseInfoService {

    public static final String LOG_MSG = "(纳税人基本信息实现层)";

    private final RedisService redisService;

    private final DmzApiClientService dmzApiClientService;

    private final VmsEnterpriseInfoMapper enterpriseInfoMapper;

    private final VmsEnterpriseInfoLogMapper enterpriseInfoLogMapper;

    @Override
    public Result<VmsEnterpriseInfoVO> getVmsEnterpriseInfo() {
        LambdaQueryWrapper<VmsEnterpriseInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(VmsEnterpriseInfo::getDeptCode, SecurityUtils.getDeptCode());
        VmsEnterpriseInfo vmsEnterpriseInfo = enterpriseInfoMapper.selectOne(queryWrapper);
        VmsEnterpriseInfoVO vo = new VmsEnterpriseInfoVO();
        if (vmsEnterpriseInfo != null) {
            BeanUtils.copyBeanProp(vo, vmsEnterpriseInfo);
        }
        return Result.OK(vo);

    }

    /**
     * 调用乐企接口获取纳税人基本信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> getVmsEnterpriseInfoByLq(BaseNsrRequestParams params, TokenUser tokenUser) {
        // 调用乐企接口获取纳税人基本信息
        Result<QueryEnterpriseInfoVO> result = dmzApiClientService.queryEnterpriseInfo(params, null);

        // 先记录日志操作
        VmsEnterpriseInfoLog enterpriseInfoLog = new VmsEnterpriseInfoLog();
        enterpriseInfoLog.setDeptCode(params.getDeptCode());
        enterpriseInfoLog.setNsrsbh(params.getNsrsbh());
        enterpriseInfoLog.setCreateTime(new Date());
        enterpriseInfoLog.setCreateUser(tokenUser.getUserCode());
        enterpriseInfoLog.setCreateUsername(tokenUser.getUserName());

        if (ResponseEnum.SUCCESS.getCode().equals(result.getCode())) {
            log.info("{}调用DMZ查询纳税人基本信息成功", LOG_MSG);
            QueryEnterpriseInfoVO data = result.getData();
            // 企业行业性质、消费税纳税人类型特殊处理
            List<String> qyhyxz = new ArrayList<>();
            List<String> xfsnsrlx = new ArrayList<>();
            List<QueryEnterpriseInfoVO.QyhyxzGrid> qyhyxzGridList = data.getQyhyxzGrid();
            if (CollectionUtil.isNotEmpty(qyhyxzGridList)) {
                for (QueryEnterpriseInfoVO.QyhyxzGrid qyhyxzGrid : qyhyxzGridList) {
                    qyhyxz.add(qyhyxzGrid.getQyhyxzdm());
                }
            }
            List<QueryEnterpriseInfoVO.XfsnsrlxGrid> xfsnsrlxGridList = data.getXfsnsrlxGrid();
            if (CollectionUtil.isNotEmpty(qyhyxzGridList)) {
                for (QueryEnterpriseInfoVO.XfsnsrlxGrid xfsnsrlxGrid : xfsnsrlxGridList) {
                    xfsnsrlx.add(xfsnsrlxGrid.getXfsnsrlxdm());
                }
            }

            BeanUtils.copyBeanProp(enterpriseInfoLog, data.getJcxx());
            enterpriseInfoLog.setOperateStatus(CommonConstant.STR_01);
            enterpriseInfoLog.setOperateMsg(JSONObject.toJSONString(data));
            enterpriseInfoLog.setCkqyfldm(StringUtils.isBlank(data.getJcxx().getCkqyfldm()) ? CommonConstant.STR_00 : data.getJcxx().getCkqyfldm());
            enterpriseInfoLog.setZfjglxdm(StringUtils.isBlank(data.getJcxx().getZfjglxdm()) ? CommonConstant.STR_00 : data.getJcxx().getZfjglxdm());
            if (CollectionUtil.isNotEmpty(qyhyxz)) {
                enterpriseInfoLog.setQyhyxzdm(String.join(CommonConstant.STRING_COMMA, qyhyxz));
            }
            if (CollectionUtil.isNotEmpty(xfsnsrlx)) {
                enterpriseInfoLog.setXfsnsrlxdm(String.join(CommonConstant.STRING_COMMA, xfsnsrlx));
            }
            enterpriseInfoLogMapper.insert(enterpriseInfoLog);

            // 查询数据库是否有记录，无则新增，有则更新
            LambdaQueryWrapper<VmsEnterpriseInfo> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(VmsEnterpriseInfo::getDeptCode, params.getDeptCode());
            VmsEnterpriseInfo entInfo = enterpriseInfoMapper.selectOne(queryWrapper);

            VmsEnterpriseInfo vmsEnterpriseInfo = new VmsEnterpriseInfo();
            // Bean转换
            BeanUtils.copyBeanProp(vmsEnterpriseInfo, data.getJcxx());
            vmsEnterpriseInfo.setLogId(enterpriseInfoLog.getId());
            vmsEnterpriseInfo.setDeptCode(params.getDeptCode());
            vmsEnterpriseInfo.setUpdateTime(new Date());
            vmsEnterpriseInfo.setUpdateUser(tokenUser.getUserCode());
            vmsEnterpriseInfo.setUpdateUsername(tokenUser.getUserName());
            vmsEnterpriseInfo.setCkqyfldm(StringUtils.isBlank(data.getJcxx().getCkqyfldm()) ? CommonConstant.STR_00 : data.getJcxx().getCkqyfldm());
            vmsEnterpriseInfo.setZfjglxdm(StringUtils.isBlank(data.getJcxx().getZfjglxdm()) ? CommonConstant.STR_00 : data.getJcxx().getZfjglxdm());
            if (CollectionUtil.isNotEmpty(qyhyxz)) {
                vmsEnterpriseInfo.setQyhyxzdm(String.join(CommonConstant.STRING_COMMA, qyhyxz));
            }
            if (CollectionUtil.isNotEmpty(xfsnsrlx)) {
                vmsEnterpriseInfo.setXfsnsrlxdm(String.join(CommonConstant.STRING_COMMA, xfsnsrlx));
            }
            if (entInfo != null && entInfo.getId() != 0) {
                vmsEnterpriseInfo.setId(entInfo.getId());
                this.updateById(vmsEnterpriseInfo);
            } else {
                vmsEnterpriseInfo.setCreateTime(new Date());
                vmsEnterpriseInfo.setCreateUser(tokenUser.getUserCode());
                vmsEnterpriseInfo.setCreateUsername(tokenUser.getUserName());
                this.save(vmsEnterpriseInfo);
            }
            // 刷新redis缓存
            String redisKey = String.format(RedisConstant.REDIS_VMSENTERPRISEINFO_CACHE_KEY, params.getDeptCode());
            redisService.setCacheObject(redisKey, JSONObject.toJSONString(vmsEnterpriseInfo), RedisConstant.REDIS_EXPIRE_TIME_6H, TimeUnit.SECONDS);
        } else {
            log.error("{}调用DMZ查询纳税人基本信息失败，原因：{}", LOG_MSG, result.getMessage());
            enterpriseInfoLog.setOperateStatus(CommonConstant.STR_02);
            enterpriseInfoLog.setOperateMsg(result.getMessage());
            enterpriseInfoLogMapper.insert(enterpriseInfoLog);
            return Result.ERROR(result.getCode(), result.getMessage());
        }
        return Result.OK_MSG(ResponseEnum.LEQI_SUCCESS.getMsg());
    }

    @Override
    public VmsEnterpriseInfo getInfoByRedis(String deptCode) {
        String redisKey = String.format(RedisConstant.REDIS_VMSENTERPRISEINFO_CACHE_KEY, deptCode);
        String redisValue = redisService.getCacheObject(redisKey);
        if (StringUtils.isBlank(redisValue)) {
            VmsEnterpriseInfo vmsEnterpriseInfo = getOne(new LambdaQueryWrapper<VmsEnterpriseInfo>()
                    .eq(VmsEnterpriseInfo::getDeptCode, deptCode));
            if (vmsEnterpriseInfo != null) {
                redisValue = JSONObject.toJSONString(vmsEnterpriseInfo);
                redisService.setCacheObject(redisKey, redisValue, RedisConstant.REDIS_EXPIRE_TIME_6H, TimeUnit.SECONDS);
            } else {
                return null;
            }
        }
        return JSONObject.parseObject(redisValue, VmsEnterpriseInfo.class);
    }

    @Override
    public String getNsrsbh() {
        String nsrsbh;
        VmsEnterpriseInfo vmsEnterpriseInfo = getInfoByRedis(SecurityUtils.getDeptCode());
        if (vmsEnterpriseInfo != null) {
            nsrsbh = vmsEnterpriseInfo.getNsrsbh();
        } else {
            nsrsbh = "";
        }
        return nsrsbh;
    }

    @Override
    public String getNsrsbh(String deptCode) {
        String nsrsbh;
        VmsEnterpriseInfo vmsEnterpriseInfo = getInfoByRedis(deptCode);
        if (vmsEnterpriseInfo != null) {
            nsrsbh = vmsEnterpriseInfo.getNsrsbh();
        } else {
            nsrsbh = "";
        }
        return nsrsbh;
    }

    public String getNsrmc() {
        String nsrmc;
        VmsEnterpriseInfo vmsEnterpriseInfo = getInfoByRedis(SecurityUtils.getDeptCode());
        if (vmsEnterpriseInfo != null) {
            nsrmc = vmsEnterpriseInfo.getNsrmc();
        } else {
            nsrmc = "";
        }
        return nsrmc;
    }

    /**
     * 判断开票方纳税人状态 “非正常” 或 “报验中”
     *
     * @param deptCode
     */
    @Override
    public void checkStatus(String deptCode, String type) {
        VmsEnterpriseInfo vmsEnterpriseInfo = getInfoByRedis(deptCode);
        if (vmsEnterpriseInfo != null) {
            String nsrztdm = vmsEnterpriseInfo.getNsrztdm();
            if (!EnterpriseInfoStateEnum.NORMAL.getKey().equals(nsrztdm) && !EnterpriseInfoStateEnum.REPORT.getKey().equals(nsrztdm)) {
                if ("1".equals(type)) {
                    throw new BusinessException(ResponseEnum.ENTERPRISE_INFO_ERROR_01);
                }
                if ("2".equals(type)) {
                    throw new BusinessException(ResponseEnum.ENTERPRISE_INFO_ERROR_02);
                }
                if ("3".equals(type)) {
                    throw new BusinessException(ResponseEnum.ENTERPRISE_INFO_ERROR_03);
                }
                if ("4".equals(type)) {
                    throw new BusinessException(ResponseEnum.ENTERPRISE_INFO_ERROR_08);
                }
            }
        } else {
            throw new BusinessException(ResponseEnum.ENTERPRISE_INFO_ERROR_07);
        }
    }
}
